package com.mineoj.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mineoj.common.ErrorCode;
import com.mineoj.constant.CommonConstant;
import com.mineoj.exception.BusinessException;
import com.mineoj.exception.ThrowUtils;
import com.mineoj.mapper.QuestionMapper;
import com.mineoj.mapper.SolutionCommentMapper;
import com.mineoj.mapper.SolutionThumbMapper;
import com.mineoj.model.dto.solution.SolutionAddRequest;
import com.mineoj.model.dto.solution.SolutionQueryRequest;
import com.mineoj.model.entity.Solution;
import com.mineoj.model.entity.SolutionComment;
import com.mineoj.model.entity.SolutionThumb;
import com.mineoj.model.entity.User;
import com.mineoj.model.vo.SolutionVO;
import com.mineoj.model.vo.UserVO;
import com.mineoj.service.UserService;
import com.mineoj.utils.SqlUtils;
import com.mineoj.service.SolutionService;
import com.mineoj.mapper.SolutionMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author 明月
* @description 针对表【solution(题解)】的数据库操作Service实现
* @createDate 2025-04-05 16:15:29
*/
@Service
public class SolutionServiceImpl extends ServiceImpl<SolutionMapper, Solution>
    implements SolutionService{
    @Resource
    private UserService userService;

    @Resource
    private SolutionThumbMapper solutionThumbMapper;

    @Resource
    private SolutionCommentMapper solutionCommentMapper;

    @Resource
    private SolutionMapper solutionMapper;

    @Resource
    private QuestionMapper questionMapper;


    /**
     * 校验题解参数
     * @param solution 题解
     * @param add
     */
    @Override
    public void validSolution(Solution solution, boolean add) {
        if (solution == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String title = solution.getTitle();
        String content = solution.getContent();

        // 创建时，参数不能为空
        if (add) {
            ThrowUtils.throwIf(StringUtils.isAnyBlank(title, content), ErrorCode.PARAMS_ERROR);
        }


        // 有参数则校验
        if (StringUtils.isNotBlank(title) && title.length() > 80) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "标题过长");
        }
        if (StringUtils.isNotBlank(content) && content.length() > 8192) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容过长");
        }
    }

    /**
     * 创建题解
     * @param solutionAddRequest
     * @param loginUser
     * @return
     */
    @Override
    public long doSolution(SolutionAddRequest solutionAddRequest, User loginUser) {
        Solution solution = new Solution();
        BeanUtils.copyProperties(solutionAddRequest, solution);

        // 校验
        this.validSolution(solution, true);
        // 题目是否存在
        long questionId = solutionAddRequest.getQuestionId();
        if (questionMapper.selectById(questionId) == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "题目不存在");
        }

        //  设置初始状态
        long userId = loginUser.getId();
        solution.setUserId(userId);
        solution.setCommentNum(0);
        solution.setThumbNum(0);

        boolean save = this.save(solution);
        if (!save) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据插入失败");
        }
        return solution.getId();
    }

    /**
     * 获取查询包装类
     *
     * @param solutionQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<Solution> getQueryWrapper(SolutionQueryRequest solutionQueryRequest) {
        QueryWrapper<Solution> queryWrapper = new QueryWrapper<>();
        if (solutionQueryRequest == null) {
            return queryWrapper;
        }
        String title = solutionQueryRequest.getTitle();
        String content = solutionQueryRequest.getContent();
        Long questionId = solutionQueryRequest.getQuestionId();
        Long userId = solutionQueryRequest.getUserId();
        String sortField = solutionQueryRequest.getSortField();
        String sortOrder = solutionQueryRequest.getSortOrder();
        String searchText = solutionQueryRequest.getSearchText();

        // 拼接查询条件
        if (StringUtils.isNotBlank(searchText)) {
            queryWrapper.and(qw -> qw.like("title", searchText).or().like("content", searchText));
        }
        queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
        queryWrapper.like(StringUtils.isNotBlank(content), "content", content);

        // 精确匹配
        queryWrapper.eq(ObjectUtils.isNotEmpty(questionId), "questionId", questionId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);


        // 排序逻辑
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }


    /**
     * 获取题目封装，并关联查询用户信息
     * @param solution
     * @param request
     * @return
     */
    @Override
    public SolutionVO getSolutionVO(Solution solution, HttpServletRequest request) {
        SolutionVO solutionVO = SolutionVO.objToVo(solution);
        long solutionId = solution.getId();
        // 1. 关联查询用户信息
        Long userId = solution.getUserId();
        User user = null;
        if (userId != null && userId > 0) {
            user = userService.getById(userId);
        }
        UserVO userVO = userService.getUserVO(user);
        solutionVO.setUserVO(userVO);

        // 2. 已登录，获取用户点赞、状态
        User loginUser = userService.getLoginUserPermitNull(request);
        if (loginUser != null) {
            // 获取点赞
            QueryWrapper<SolutionThumb> solutionThumbQueryWrapper = new QueryWrapper<>();
            solutionThumbQueryWrapper.in("solutionId", solutionId);
            solutionThumbQueryWrapper.eq("userId", loginUser.getId());
            SolutionThumb solutionThumb = solutionThumbMapper.selectOne(solutionThumbQueryWrapper);
            solutionVO.setHasThumb(solutionThumb != null);
        }
        return solutionVO;
    }

    /**
     * 将题解列表转换为题解视图列表，并关联查询用户信息（脱敏）
     * @param solutionPage
     * @param request
     * @return
     */
    @Override
    public Page<SolutionVO> getSolutionVOPage(Page<Solution> solutionPage, HttpServletRequest request) {
        List<Solution> solutionList = solutionPage.getRecords();
        Page<SolutionVO> solutionVOPage = new Page<>(solutionPage.getCurrent(), solutionPage.getSize(), solutionPage.getTotal());
        if (CollUtil.isEmpty(solutionList)) {
            return solutionVOPage;
        }
        // 1. 关联查询用户信息
        Set<Long> userIdSet = solutionList.stream().map(Solution::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        // 2. 已登录，获取用户点赞、收藏状态
        Map<Long, Boolean> solutionIdHasThumbMap = new HashMap<>();
        Map<Long, Boolean> solutionIdHasFavourMap = new HashMap<>();
        User loginUser = userService.getLoginUserPermitNull(request);
        if (loginUser != null) {
            Set<Long> solutionIdSet = solutionList.stream().map(Solution::getId).collect(Collectors.toSet());
            loginUser = userService.getLoginUser(request);
            // 获取点赞
            QueryWrapper<SolutionThumb> solutionThumbQueryWrapper = new QueryWrapper<>();
            solutionThumbQueryWrapper.in("solutionId", solutionIdSet);
            solutionThumbQueryWrapper.eq("userId", loginUser.getId());
            List<SolutionThumb> solutionSolutionThumbList = solutionThumbMapper.selectList(solutionThumbQueryWrapper);
            solutionSolutionThumbList.forEach(solutionSolutionThumb -> solutionIdHasThumbMap.put(solutionSolutionThumb.getSolutionId(), true));

        }

        // 填充信息
        List<SolutionVO> solutionVOList = solutionList.stream().map(solution -> {
            SolutionVO solutionVO = SolutionVO.objToVo(solution);
            Long userId = solution.getUserId();
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            solutionVO.setUserVO(userService.getUserVO(user));
            solutionVO.setHasThumb(solutionIdHasThumbMap.getOrDefault(solution.getId(), false));
            return solutionVO;
        }).collect(Collectors.toList());
        solutionVOPage.setRecords(solutionVOList);
        return solutionVOPage;
    }

    /**
     * 删除题解
     * @param id
     * @return
     */
    @Override
    @Transactional
    public boolean deleteById(long id) {
        if (solutionMapper.deleteById(id) > 0) {
            // 删除点赞
            solutionThumbMapper.delete(new QueryWrapper<SolutionThumb>().eq("solutionId", id));
            // 删除评论
            solutionCommentMapper.delete(new QueryWrapper<SolutionComment>().eq("solutionId", id));
            return true;
        }
        return true;
    }


}




